﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;

public static class Utility
{
    static public T[] Enlarge<T>(T[] old, int length = -1)
    {
        if (length <= 0)
            length = old.Length * 2;
        if (length < old.Length)
            throw new Exception("length must bigger than old arr");
        T[] re = new T[length];
        for (int i = 0; i < old.Length; i++)
            re[i] = old[i];
        return re;
    }
    static public bool CharMatch(char c, params char[] matchs)
    {
        for (int i = 0; i < matchs.Length; i++)
            if (c == matchs[i])
                return true;
        return false;
    }
    static public bool CharMatch(char c, string match)
    {
        char[] matchs = match.ToArray();
        for (int i = 0; i < matchs.Length; i++)
            if (c == matchs[i])
                return true;
        return false;
    }
    static public bool Between(int value, int min, int max, bool contain_min_max = true)
    {
        return contain_min_max ? value >= min && value <= max : value > min && value < max;
    }
    static public int LimitBetween(int value, int min, int max)
    {
        if (value < min)
            value = min;
        else if (value > max)
            value = max;
        return value;
    }

    /// <summary>
    /// 绘制菱形扩展方法
    /// </summary>
    static public void DrawDiamond(this Graphics g, Pen pen, Rectangle rect)
    {
        g.DrawParallelogram(pen, rect, 0.5f, 0.5f);
    }
    /// <summary>
    /// 绘制平行四边形扩展方法
    /// </summary>
    static public void DrawParallelogram(this Graphics g, Pen pen, Rectangle rect, float xdiffer, float ydiffer)
    {
        Point p1 = new Point((int)(rect.X + rect.Width * xdiffer), rect.Y);
        Point p2 = new Point(rect.X + rect.Width, (int)(rect.Y + ydiffer * rect.Height));
        Point p3 = new Point((int)(rect.X + rect.Width - rect.Width * xdiffer), rect.Y + rect.Height);
        Point p4 = new Point(rect.X, (int)(rect.Y + rect.Height - ydiffer * rect.Height));
        g.DrawLine(pen, p1, p2);
        g.DrawLine(pen, p2, p3);
        g.DrawLine(pen, p3, p4);
        g.DrawLine(pen, p4, p1);
    }
    static public void FillDiamond(this Graphics g, Brush brush, Rectangle rect)
    {
        g.FillParallelogram(brush, rect, 0.5f, 0.5f);
    }
    static public void FillParallelogram(this Graphics g, Brush brush, Rectangle rect, float xdiffer, float ydiffer)
    {
        Point p1 = new Point((int)(rect.X + rect.Width * xdiffer), rect.Y);
        Point p2 = new Point(rect.X + rect.Width, (int)(rect.Y + ydiffer * rect.Height));
        Point p3 = new Point((int)(rect.X + rect.Width - rect.Width * xdiffer), rect.Y + rect.Height);
        Point p4 = new Point(rect.X, (int)(rect.Y + rect.Height - ydiffer * rect.Height));
        g.FillPath(brush, new GraphicsPath(new Point[] {
            p1,p2,p3,p4
        }, new byte[] { 1, 1, 1, 1 }));
    }

    /// <summary>
    /// 绘制一个箭头  xpercent,ypercent 矩形部分占总长度的百分比和高度的百分比
    /// </summary>
    static public void FillArrow(this Graphics g, Brush brush, Rectangle rect, float xpercent, float ypercent)
    {
        g.FillRectangle(new SolidBrush(Color.Red), rect.X, rect.Y + rect.Height * (1 - ypercent) / 2, rect.Width * xpercent, rect.Height * ypercent);
        g.FillPolygon(new SolidBrush(Color.Red), new PointF[] {
                    new PointF(rect.X+xpercent*rect.Width,rect.Y),
                    new PointF(rect.X+xpercent*rect.Width,rect.Bottom),
                    new PointF(rect.Right,rect.Y+rect.Height/2),
                });
    }


    static public bool IsInEllipse(Point pos, Rectangle ellipse)
    {
        return Math.Pow(pos.X - ellipse.X, 2) / Math.Pow(ellipse.Width, 2) + Math.Pow(pos.Y - ellipse.Y, 2) / Math.Pow(ellipse.Height, 2) <= 1;
    }
    static public bool IsInCircular(Point pos, Point circularcenter, int r)
    {
        return Math.Pow(pos.X - circularcenter.X, 2) + Math.Pow(pos.Y - circularcenter.Y, 2) <= Math.Pow(r, 2);
    }

    static public Rectangle Rotate_90(this Rectangle rect)
    {
        return new Rectangle(-rect.Y - rect.Height, rect.X, rect.Height, rect.Width);
    }
    static public Rectangle Rotate_180(this Rectangle rect)
    {
        return new Rectangle(-rect.X - rect.Width, -rect.Y - rect.Height, rect.Width, rect.Height);
    }
    static public Rectangle Rotate_270(this Rectangle rect)
    {
        return new Rectangle(rect.Y, -rect.X - rect.Width, rect.Height, rect.Width);
    }
    static public Point Rotate_90(this Point p)
    {
        return new Point(-p.Y, p.X);
    }
    static public Point Rotate_180(this Point p)
    {
        return new Point(-p.X, -p.Y);
    }
    static public Point Rotate_270(this Point p)
    {
        return new Point(p.Y, -p.X);
    }


    static public T Limit<T>(T v, T min, T max) where T : IComparable
    {
        if (v.CompareTo(min) < 0)
        {
            return min;
        }
        if (v.CompareTo(max) > 0)
        {
            return max;
        }
        return v;
    }

}

